package com.jackrain.nea.clould.services;

import com.alibaba.dubbo.common.utils.NetUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.util.TypeUtils;
import com.jackrain.nea.clould.dao.CloudErrorDao;
import com.jackrain.nea.clould.dao.PlantDao;
import com.jackrain.nea.clould.dao.StoreKeyDao;
import com.jackrain.nea.clould.dao.ThirdLogDao;
import com.jackrain.nea.clould.model.CloudErrorModel;
import com.jackrain.nea.clould.model.ThirdLogModel;
import com.jackrain.nea.clould.utils.ObjectToUtil;
import com.jackrain.nea.exception.NDSException;
import com.jackrain.nea.sys.Command;
import com.jackrain.nea.sys.CommandAdapter;
import com.jackrain.nea.util.HttpUtils;
import com.jackrain.nea.util.ValueHolder;
import com.jackrain.nea.web.query.QueryEngine;
import com.taobao.api.DefaultTaobaoClient;
import com.taobao.api.TaobaoClient;
import com.taobao.api.request.FenxiaoProductQuantityUpdateRequest;
import com.taobao.api.request.ItemQuantityUpdateRequest;
import com.taobao.api.response.FenxiaoProductQuantityUpdateResponse;
import com.taobao.api.response.ItemQuantityUpdateResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.FastDateFormat;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.security.MessageDigest;
import java.util.HashMap;

/**
 * Created by zc on 2017/7/11.
 */
@Slf4j
@Service
public class CallInterfaceService extends CommandAdapter implements Command {


    @Autowired
    private CloudErrorDao mCloudErrorDao;

    @Autowired
    private ThirdLogDao mThirdLogDao;


    @Override
    public ValueHolder execute(HashMap hashMap) throws NDSException{
        ValueHolder vh = new ValueHolder();

        JSONObject params = (JSONObject) hashMap.get("PARAM");
        String origMsgKey = ObjectToUtil.getString(hashMap.get("MSGKEY"), "");
        Long adClientId = params.getLong("clientId");
        String topic = params.getString("topic");
        String tagSrc = params.getString("tag");
        Object data = params.get("data");

        log.info("params ->"+params.toJSONString());

        log.info("origMsgKey ->"+origMsgKey);

        //查询topicid
        String topicSql = "SELECT ID FROM OMS_TOPIC WHERE TOPIC=?";
        JSONObject topicJson = QueryEngine.getInstance().doQueryObject(topicSql, new Object[]{topic});
        Long topicId = topicJson.getLong("ID");

        //查询accesssecret和accesskey以及请求地址
        String plantSql = "SELECT e.ID,a.ACCESSSECRET,a.ACCESSKEY,b.INTERFACE\n" +
                "FROM OMS_THIRD_PLANT a\n" +
                "LEFT JOIN oms_plant e on a.CODE=e.NO\n"+
                "LEFT JOIN oms_third_interface  b on a.ID=b.OMS_THIRD_PLANT_ID\n" +
                "LEFT JOIN oms_topic c on b.TOPICID = c.ID\n" +
                "LEFT JOIN oms_tag d on b.OMSTAGID = d.ID\n" +
                "WHERE d.TAGNAME=? AND c.TOPIC=?;\n";

        JSONObject plantJson = QueryEngine.getInstance().doQueryObject(plantSql, new Object[]{tagSrc, topic});


        if(plantJson == null){
            vh.put("code",-1);
            vh.put("message","tag:"+tagSrc+" topic:"+topic+"接口未维护");
            recCloudError("接口错误", "tag:"+tagSrc+" topic:"+topic+"接口未维护",origMsgKey);
        }
        String accesssecret = plantJson.getString("ACCESSSECRET");
        String accesskey = plantJson.getString("ACCESSKEY");
        String host = plantJson.getString("INTERFACE");


        String date = FastDateFormat.getInstance("yyyy/MM/dd HH:mm:ss").format(System.currentTimeMillis());
        String info = accesskey + accesssecret + date;
        String serverDigest = null;
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.update(info.getBytes("UTF8"));
            byte[] s = messageDigest.digest();
            serverDigest = convertToHexString(s);

        } catch (Exception e) {
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            e.printStackTrace(pw);
            vh.put("code",-1);
            vh.put("message",sw.toString());
            recCloudError("接口错误", "tag:"+tagSrc+" topic:"+topic+"error:"+sw.toString(),origMsgKey);
        }

        HashMap body = new HashMap();
        HashMap head = new HashMap();
        JSONArray ja = new JSONArray();
        ja.add(data);
        String param = JSON.toJSONString(ja,new SerializerFeature[]{SerializerFeature.WriteMapNullValue});
        head.put("accessKey", accesskey);
        head.put("sign", serverDigest);
        head.put("dateTime", date);
        head.put("TAG", tagSrc);
        body.put("DATA",param);
        JSONObject response=null;
        try {
            response = postHttp(host,head,body);
            if(response.getInteger("code") < 0){
                throw new NDSException(response.getString("message"));
            }
            log.info("execute end return "+response);
            vh.put("code",0);
            recThirdLog(plantJson.getIntValue("ID"),plantJson.getString("INTERFACE"),(JSONObject) data,response.toJSONString());
        } catch(Exception e) {
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            e.printStackTrace(pw);
            if(response.getInteger("code") != null){
                vh.put("code",response.getInteger("code"));
                vh.put("message",response.getString("message"));
            }else{
                vh.put("code",-1);
                vh.put("message",sw.toString());
            }
            //记录错误日志
            recCloudError("接口调用",sw.toString(), origMsgKey);
            recThirdLog(plantJson.getIntValue("ID"),plantJson.getString("INTERFACE"),(JSONObject) data,response.toJSONString());
        }
        return vh;
    }


    public JSONObject postHttp(String host,HashMap head,HashMap body)throws Exception{
        HttpResponse s = null;
        JSONObject ret = new JSONObject();
        int status;
        s = HttpUtils.doPost(host, null, head, null, body);
        status = s.getStatusLine().getStatusCode();
        String response = EntityUtils.toString(s.getEntity());

        if (status == 200) {
            ret = JSONObject.parseObject(response);
            if(ret == null || ret.getInteger("code") == null){
                ret.put("code",-1);
                ret.put("message","调用接口："+host+"，状态："+status+"，异常：没有返回值");
            }
        }else{
            ret.put("code",-1);
            ret.put("message","调用接口："+host+"，状态："+status+"异常："+response);
        }

        return ret;
    }

    public static String convertToHexString(byte data[]) {
        StringBuffer strBuffer = new StringBuffer();
        for (int i = 0; i < data.length; i++) {
            strBuffer.append(Integer.toHexString(0xff & data[i]));
        }
        return strBuffer.toString();
    }


    private void recCloudError(String name, String errorinfo, String origMsgKey) {

        //记录错误日志
        CloudErrorModel cloudErrorModel = new CloudErrorModel();
        cloudErrorModel.setName(name);
        cloudErrorModel.setErrorinfo(errorinfo);
        cloudErrorModel.setIp(NetUtils.getLocalAddress().getHostAddress());
        cloudErrorModel.setPtype("1");//1:服务器日志2:客户端日志
        cloudErrorModel.setOrigmsgkey(origMsgKey);
        try {
            mCloudErrorDao.insert(cloudErrorModel);//
        } catch (Exception e1) {
           log.error(e1.getMessage(),e1);
        }

    }

    private void recThirdLog(int oms_plantid, String url,JSONObject paramObject, String callbackinfo){

        //记录成功日志
        ThirdLogModel thirdLogModel = new ThirdLogModel();
        thirdLogModel.setOms_plantid(oms_plantid);
        thirdLogModel.setApiurl(url);
        thirdLogModel.setCallbackinfo(callbackinfo);
        thirdLogModel.setParm(JSON.toJSONString(paramObject,new SerializerFeature[]{SerializerFeature.WriteMapNullValue}));
        try{
            mThirdLogDao.insert(thirdLogModel);
        }catch(Exception e1){
            log.error(e1.getMessage(),e1);
        }


    }
}
